<?php


namespace app\api\controller;

use app\api\model\DtsGame;
use app\api\model\DtsRecord;
use app\api\model\User as UserModel;
use app\api\model\UserPointsLog;
use app\api\services\DtsService;
use Fund\Points\Sub;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\facade\Db;
use think\response\Json;


class BattleRoyale extends Api
{
    /**
     * {@inheritdoc}
     * rules:
     * actions 控制器列表: * 全部控制器
     * roles 允许访问角色:
     * all 全部;
     * no_all 不允许任何人进;
     * login 登录(默认);
     * allow 验证规则:
     * no_checkTime 不验证时间戳;
     * no_checkSign  不验证签名;
     */
    protected $auth = [
        [
            'actions' => ['*'],
            'roles' => 'all',
            'allow' => ["no_checkSign"],
        ]
    ];

    public function initGame(): Json
    {
        $game = DtsGame::order('id', 'desc')->limit(1)->find();
        if (!$game) {
            fault('未开始');
        }
        $user = UserModel::find($this->userId);
        $balance = $user['balance'];
        if (!DtsService::exist($game->id, $user->id)) {
            DtsService::joinGame($user, $game);
        }
        $data = [
            'balance' => $balance,
            'game_id' => $game->id,
            'pre_killer_room' => $game->pre_killer_room
        ];
        return data($data);
    }

    //投注列表
    public function battleList()
    {
        $list = Db::name("invest")->field("id,num")->select()->toArray();
        return data($list);
    }

    //离开房间
    public function quitGame($game_id): Json
    {
        $user = UserModel::find($this->userId);
        $game = DtsGame::find($game_id);
        if (!$game) {
            fault('未开始');
        }
        DtsService::removeGameUserList($user, $game);
        return success('操作成功');
    }

    /**
     * 参与下注
     * @param $game_id
     * @param $room_id
     * @param $amount
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function join($game_id, $room_id, $amount): Json
    {
//        $status = Db::name("application")->where("id", 2)->value("status");
//        if ($status != 1) {
//            fault('游戏未开启，禁止下注');
//        }

        $payment_type = 'points';

        $amount = (float)$amount;

        $room_id = (int)$room_id;
        if ($room_id <= 0 || $room_id > 8) {
            fault('房间编号错误');
        }

        //封盘检测，禁止下注
        if (Cache::store("redis")->get('game_dts_lock_flag')) {
            fault('结算中');
        }

        $user = UserModel::find($this->userId);
        $game = DtsGame::find($game_id);
        if ($game->state == 3) {
            //已结束
            fault('请刷新后重试');
        }

//        if ($payment_type === 'points' && $user->balance < $amount) {
//            fault('余额不足');
//        }
        Db::startTrans();
        try {
            $record = DtsRecord::where('user_id', $user->id)
                ->where('game_id', $game->id)
                ->where('payment_type', $payment_type)
                ->find();
            if ($record) {
                $total_amount = $amount + $record->amount;
                DtsRecord::where([
                    'user_id' => $user->id,
                    'game_id' => $game->id,
                    'payment_type' => $payment_type,
                ])->update([
                    'room_id' => $room_id,
                    'amount' => $total_amount,
                ]);
            } else {
                if ($amount <= 0) {
                    fault('金额错误');
                }
                $total_amount = $amount;
                $record = DtsRecord::create([
                    'game_id' => $game->id,
                    'user_id' => $user->id,
                    'room_id' => $room_id,
                    'amount' => $amount,
                    'payment_type' => $payment_type,
                ]);
            }

            DtsService::updateGame($game);
            if ($payment_type === 'points' && $amount > 0) {
                $sub = new Sub($user, $amount, UserPointsLog::BUSINESS_TYPE_GAME_DTS_OUT, ['target_id' => $record->id]);
                $sub->action();
            }
            DtsService::joinGame($user, $game, $room_id, $total_amount);
            Db::commit();
        } catch (\Exception $exception) {
            Db::rollback();
            return fault($exception->getMessage());
        }
        return success('操作成功');
    }

    //记录
    public function record()
    {
        $user = UserModel::find($this->userId);
        //近100期被杀统计
        $data = DtsGame::where('state', 3)->order('id', 'desc')->limit(100)->select();
        $kill_record = [];
        for ($i = 1; $i <= 8; $i++) {
            $kill_record[] = [
                'room_id' => $i,
                'count' => $data->where('killer_room', $i)->count()
            ];
        }
        //近10期杀手房间记录
        $room_record = $data->slice(0, 10)->map(function ($item) {
            return [
                'game_id' => $item->id,
                'killer_room' => $item->killer_room,
            ];
        })->toArray();

        //参与记录
        $bonus = $user->pointsLog()->where('business_type', UserPointsLog::BUSINESS_TYPE_GAME_DTS_IN)->sum('amount');
        $payout = $user->pointsLog()
            ->where('business_type', UserPointsLog::BUSINESS_TYPE_GAME_DTS_OUT)
            ->sum('amount');
        $last_record = $user->dtsRecord()
            ->field('game_id,room_id,killer_room,amount,bonus,state,create_time')
            ->append(['create_time'])
            ->whereIn('state', [1, 2])
            ->order('id', 'desc')
            ->limit(1)
            ->find();
        $last_record = [$last_record];
        $join_record = compact('bonus', 'payout', 'last_record');

        return data(compact('kill_record', 'room_record', 'join_record'));
    }

    //更多记录
    public function record2(int $page = 1, int $limit = 10)
    {
        $user = UserModel::find($this->userId);
        $model = $user->dtsRecord()
            ->field('game_id,room_id,killer_room,amount,bonus,state,create_time')
            ->append(['create_time'])
            ->whereIn('state', [1, 2]);
        $list = $model->order('id', 'desc')->page($page, $limit)->select()->toArray();
        return data($list);
    }

    //排行榜
    public function rankList($type = 'week')
    {
        $user = UserModel::find($this->userId);
        if ($type == 'week') {
            $rankList = Db::name("dts_record")->whereTime("create_time", "today")->field("sum(amount) as price,user_id as id")->group("user_id")->order("price desc")->limit(10)->select()->toArray();
            $sum = Db::name("dts_record")->whereTime("create_time", "today")->where("user_id", $this->userId)->sum("amount");
        } else {
            $rankList = Db::name("dts_record")->whereTime("create_time", "yesterday")->field("sum(amount) as price,user_id as id")->group("user_id")->order("price desc")->limit(10)->select()->toArray();
            $sum = Db::name("dts_record")->whereTime("create_time", "yesterday")->where("user_id", $this->userId)->sum("amount");
        }
        $rank = 0;
        foreach ($rankList as $k => $v) {
            if ($v['id'] == $this->userId) {
                $rank = $k + 1;
            }
            $info = Db::name("member")->where("id", $v['id'])->field("id,nickname,avatar")->find();
            $rankList[$k]['avatarUrl'] = get_image_url($info['avatar']);
            $rankList[$k]['nickName'] = $info['nickname'];
            $rankList[$k]['amount'] = $v['price'];
        }
        $userRank = [
            'rank' => $rank,
            'avatarUrl' => get_image_url($user->avatar),
            'nickName' => $user->nickname,
            'amount' => $sum,
        ];

        return json(["msg" => "成功", "data" => ['rankList' => $rankList, 'userRank' => $userRank], "code" => 200]);
    }
}